package com.hsylient.javase.chapter14.asymmetric;

import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Test;

import java.nio.charset.StandardCharsets;

/**
 * 非对称加密
 */
@Slf4j
public class AsymmetricTest {

    @Test
    public void testRSA() {
        RSA rsa = new RSA();

        //获得私钥
        rsa.getPrivateKey();
        log.info("RSA私钥的Base64字符串形式：{}", rsa.getPrivateKeyBase64());

        //获得公钥
        rsa.getPublicKey();
        log.info("RSA公钥的Base64字符串形式：{}", rsa.getPublicKeyBase64());

        //公钥加密，私钥解密
        byte[] encrypt = rsa.encrypt(StrUtil.bytes("我是一段测试aaaa", CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey);
        log.info("RSA公钥加密后的字节数组转Base64: {}", Base64Encoder.encode(encrypt));
        byte[] decrypt = rsa.decrypt(encrypt, KeyType.PrivateKey);

        //Junit单元测试
        Assert.assertEquals("我是一段测试aaaa", StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8));

        //私钥加密，公钥解密
        byte[] encrypt2 = rsa.encrypt(StrUtil.bytes("我是一段测试aaaa", CharsetUtil.CHARSET_UTF_8), KeyType.PrivateKey);
        log.info("RSAs私钥加密后的字节数组转Base64: {}", Base64Encoder.encode(encrypt2));
        byte[] decrypt2 = rsa.decrypt(encrypt2, KeyType.PublicKey);

        //Junit单元测试
        Assert.assertEquals("我是一段测试aaaa", StrUtil.str(decrypt2, CharsetUtil.CHARSET_UTF_8));

    }


    @Test
    public void testRSAEncrypt() {

        // 被加密内容
        String text = "我想她";

        // 私钥
        RSA rsa = new RSA();
        String privateKeyBase64 = rsa.getPrivateKeyBase64();
        log.info("RSA私钥的Base64字符串形式：{}", privateKeyBase64);

        // 公钥
        String publicKeyBase64 = rsa.getPublicKeyBase64();
        log.info("RSA公钥的Base64字符串形式：{}", publicKeyBase64);

        // 使用私钥加密
        byte[] encrypt = rsa.encrypt(text, KeyType.PrivateKey);

        // 将加密后的字节数组转换为十六进制字符串
        String hexStr = HexUtil.encodeHexStr(encrypt);

        // 598f7c2325ceabc7f203cd8ada2cc99a2b14271e574f936c5810ac8210c72507a73b849e0dc1787a339bee14a301fa53e33c1504140ebb95035587fdd614d40576a42ed1a1c2fd17c2c94d8f49c387c2fd7f57cc905534be5ef0f9f3ab87c68b9cc7c88947a45b6c20f37f55d01780f44ded53a9c3bbfc13d9178ca7adf2ccd5
        log.info("将加密后的字节数组转换为十六进制字符串:{}", hexStr);


    }

    @Test
    public void testRSADecrypt() {

        // 已知密文：0e74ba63d7295934171a7df6e01da9cbfdfe591e2361274e1a0c0286ef507e9c3d3d0bdd3b97dab81fa2d5696f8e0ab30828ad4d86a3ab21c44154ed3795850768db088d55458cbacb24c8e8e851662fe28e2599f5c4714fdffce35c7fecad5f846ac81d8e369ebbadc64f0095127596090a489512f5ab95fc303c11054cd04f
        // 已知公钥：MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCX3HjLsQcg6pIgHqf8CeKzsM2kDPoxaI49Njx+s9Im0mldSGMJ+NsJualiL0gqm7junpuRAfIZAMgoRzA8HPj0bFSN8j4Tr9GR2RxcfSXztKxCZNvYDLf8cF8dDdCagJECd9OmcjiWU6lLJZPUpm6/dwI3ji7XqtZQ10L6FFnxTwIDAQAB

        // 使用十六进制字符串转字节数组
        byte[] txtBytes = HexUtil.decodeHex("0e74ba63d7295934171a7df6e01da9cbfdfe591e2361274e1a0c0286ef507e9c3d3d0bdd3b97dab81fa2d5696f8e0ab30828ad4d86a3ab21c44154ed3795850768db088d55458cbacb24c8e8e851662fe28e2599f5c4714fdffce35c7fecad5f846ac81d8e369ebbadc64f0095127596090a489512f5ab95fc303c11054cd04f");

        RSA rsa = SecureUtil.rsa(null, "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCX3HjLsQcg6pIgHqf8CeKzsM2kDPoxaI49Njx+s9Im0mldSGMJ+NsJualiL0gqm7junpuRAfIZAMgoRzA8HPj0bFSN8j4Tr9GR2RxcfSXztKxCZNvYDLf8cF8dDdCagJECd9OmcjiWU6lLJZPUpm6/dwI3ji7XqtZQ10L6FFnxTwIDAQAB");

        // 解密后的字节数组
        byte[] decrypt = rsa.decrypt(txtBytes, KeyType.PublicKey);

        System.out.println(StrUtil.str(decrypt, StandardCharsets.UTF_8));
    }

}
